package client

import (
	"acs/comet/proto"
	"acs/pbmodel"
	"fmt"
	"time"

	pb "github.com/golang/protobuf/proto"
)

type HandleFunc func(req *proto.Request, client *Client) (pb.Message, error)

func HandlePing(_ *proto.Request, _ *Client) (pb.Message, error) {
	pr := &pbmodel.PingResp{
		Resp: pb.String("OK"),
	}
	return pr, nil
}

func HandleDefault(req *proto.Request, _ *Client) (pb.Message, error) {
	pr := &pbmodel.ProtoErr{
		Msg:  pb.String(fmt.Sprintf("unknown cmd: %v", req.Cmd)),
		Code: pb.Int(proto.CmdErrCodeUnknownCmd),
	}
	return pr, nil
}
func HandleEvent(req *proto.Request, _ *Client) (pb.Message, error) {
	re := &pbmodel.EventResp{}
	re.Status = pb.Int(6000)
	return re, nil
}

func HandleRegister(req *proto.Request, client *Client) (pb.Message, error) {
	registerInfo := &pbmodel.RegisterInfo{}
	err := pb.Unmarshal(req.Data, registerInfo)
	re := &pbmodel.RegisterInfoResp{}
	if err != nil {
		re.Msg = pb.String("Invalid register data: " + err.Error())
		re.Status = pb.Int(proto.CmdErrCodeDataDecodeErr)
		return re, nil
	}

	client.SetRegisterInfo(*registerInfo)
	client.SetHandshaked(true)
	// TODO: possible races on LastRegTime
	client.LastRegTime = time.Now().Unix()
	re.Msg = pb.String("OK")
	re.Status = pb.Int(proto.CmdHandledSuccess)
	return re, nil
}

func HandlePatchFin(req *proto.Request, client *Client) (pb.Message, error) {
	finReq := &pbmodel.Patchfin{}
	re := &pbmodel.PatchfinResp{}
	err := pb.Unmarshal(req.Data, finReq)
	if err != nil {
		re.Msg = pb.String("Invalid patchfin data: " + err.Error())
		re.Status = pb.Int(3001)
		return re, nil
	}
	regInfo := client.GetRegisterInfo()
	// TODO: validate LPID
	regInfo.LPID = finReq.LPID
	client.SetRegisterInfo(regInfo)
	re.Status = pb.Int(3000)
	return re, nil
}

func HandleSchemaFin(req *proto.Request, client *Client) (pb.Message, error) {
	finReq := &pbmodel.Schemafin{}
	re := &pbmodel.SchemafinResp{}
	err := pb.Unmarshal(req.Data, finReq)
	if err != nil {
		re.Msg = pb.String("Invalid schemafin data: " + err.Error())
		re.Status = pb.Int(4001)
	}

	regInfo := client.GetRegisterInfo()
	// TODO: validate LPID
	regInfo.LSID = finReq.LSID
	client.SetRegisterInfo(regInfo)
	re.Status = pb.Int(4000)
	return re, nil

}
